package com.mvvmhabit.org.base

import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.mvvmhabit.org.bus.Messenger
import com.mvvmhabit.org.custom.load.LoadDialog
import com.mvvmhabit.org.utils.ToastUtils
import java.lang.reflect.ParameterizedType

/**
 * @Date: 2020/10/30 10:31
 * @Author:小妖
 * @Description: Fragment 基类
 */
abstract class BaseFragment<V : ViewDataBinding, VM : BaseViewModel> : Fragment(), IBaseView {
    // 定义可以全局可以访问的 binding
    lateinit var mBinding: V
    var mViewModel: VM? = null
    private var viewModelId: Int = 0

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    abstract fun initVariableId(): Int

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    abstract fun initViewModel(): Class<VM>

    /**
     * 有返回值的抽象方法：得到布局文件
     *
     * @return layout布局文件
     */
    abstract fun initContentView(
        inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?
    ): Int

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initParam()
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        mBinding = DataBindingUtil.inflate(
            inflater,
            initContentView(inflater, container, savedInstanceState),
            container, false
        )
        return mBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        if (mViewModel == null) {
            val simpleName = this::class.simpleName
            mViewModel = ViewModelProvider(this).get(simpleName!!, initViewModel())
            viewModelId = initVariableId()
            mBinding.setVariable(viewModelId, mViewModel)
            lifecycle.addObserver(mViewModel!!)
            mViewModel?.injectLifecycleProvider(this)
            registerUIChangeLiveEventCallBack()
            initData()
            initViewObservable()
        }
        mViewModel?.registerBus()
    }

    override fun initParam() {

    }

    override fun initData() {
    }

    override fun initViewObservable() {

    }

    override fun initStatusBar() {

    }

    // 界面改变事件监听回调
    private fun registerUIChangeLiveEventCallBack() {
        // 页面跳转
        mViewModel?.getUI()?.getStartActivityEvent()?.observeForever {
            val clz: Class<*> = it[CLASS] as Class<*>
            val bundle: Any? = it[BUNDLE]
            startActivity(clz, bundle)
        }
        // 跳转到容器页面
        mViewModel?.getUI()?.getStartContainerActivityEvent()?.observeForever {
            val canonicalName = it[CANONICAL_NAME] as String
            val bundle = it[BUNDLE]
            startContainerActivity(canonicalName, bundle)
        }
        // 关闭界面
        mViewModel?.getUI()?.getFinishEvent()?.observeForever {
            activity?.finish()
        }

        mViewModel?.getUI()?.getStartIntentEvent()?.observeForever {
            startActivity(it)
        }

        mViewModel?.getUI()?.getDismissLoadDialogEvent()?.observeForever {
            dismissLoadDialog()
        }

        mViewModel?.getUI()?.getShowLoadDialogEvent()?.observeForever {
            if (TextUtils.isEmpty(it)) {
                showLoadDialog()
            } else {
                showLoadDialog(it)
            }
        }
    }

    protected fun startActivity(clz: Class<*>, bundle: Any?) {
        val intent = Intent(context, clz)
        if (bundle != null) {
            intent.putExtras(bundle as Bundle)
        }
        activity?.startActivity(intent)
    }

    protected fun startContainerActivity(canonicalName: String?, bundle: Any?) {
        val intent = Intent(context, ContainerActivity::class.java)
        intent.putExtra(FRAGMENT, canonicalName)
        if (bundle != null) {
            intent.putExtra(FRAGMENT_BUNDLE, bundle as Bundle)
        }
        activity?.startActivity(intent)
    }

    fun isBackPressed(): Boolean {
        return false
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Messenger.getDefault().unregister(mViewModel)
        if (mViewModel != null) {
            mViewModel?.removeBus()
        }
        mBinding.unbind()
        LoadDialog.destroy()
    }

    // 显示可以修改标题的
    private fun showLoadDialog(title: String) {
        LoadDialog.show(requireActivity(), title)
    }

    // 显示数据加载动画
    private fun showLoadDialog() {
        LoadDialog.show(requireActivity(), null)
    }

    // 关闭数据加载动画
    private fun dismissLoadDialog() {
        LoadDialog.dismiss()
    }
}